// Copyright 2017 wgliang. All rights reserved.
// Use of this source code is governed by Apache
// license that can be found in the LICENSE file.

// Package cli provides virtual command-line access
// in pgproxy include start,cli and stop action.
package cli

import (
	"flag"
	"fmt"
	"os"
	"strconv"
	"time"

	"../config"
	"../parser"
	"../proxy"
	"github.com/golang/glog"
)

var (
	Pc      config.ProxyConfig
)

// pgproxy Main
func Main() {
	flag.Parse()
	defer glog.Flush()
	Pc = config.ReadConfig()
	glog.Infoln("Starting pgproxy...")
	info(Pc.DB.ProxyAddr)
	logDir()
	saveCurrentPid()
	proxy.Start(Pc.DB.ProxyAddr, Pc.DB.Addr, parser.Filter, parser.Return)
	glog.Infoln("Started pgproxy successfully.")

}

// print pgproxy infomation
func info(proxyhost string) {
	hostname, err := os.Hostname()
	if err != nil {
		hostname = "<unknown>"
	}
	pid := strconv.Itoa(os.Getpid())
	starttime := time.Now().Format("2006-01-02 03:04:05 PM")
	fmt.Println("	Host: " + hostname)
	fmt.Println("	Pid:", string(pid))
	fmt.Println("	Proxy:", proxyhost)
	fmt.Println("	Starttime:", starttime)
	fmt.Println()
}

// set log dir
func logDir() {
	_, err := os.Stat("./log")
	if err != nil && os.IsNotExist(err) {
		err := os.MkdirAll("./log", 0777)
		if err != nil {
			glog.Fatalln(err)
		} else {
			glog.Infoln("glog and process pid in ./log")
		}
	}
}

// save current pgproxy pid
func saveCurrentPid() {
	// pid file
	filepath := "./log/pid.log"
	fout, err := os.OpenFile(filepath, os.O_CREATE|os.O_RDWR, 0777)
	if err != nil {
		glog.Errorln(err)
		return
	}
	defer fout.Close()
	// write current pid
	fout.WriteString(strconv.Itoa(os.Getpid()))
}

// get current pgproxy pid
func getCurrentPid() int {
	// pid file
	filepath := "./log/pid.log"
	fin, err := os.OpenFile(filepath, os.O_RDONLY, 0777)
	if err != nil {
		glog.Errorln(err)
		return 0
	}
	defer fin.Close()
	// read current pid
	buf := make([]byte, 1024)

	n, _ := fin.Read(buf)
	if 0 >= n {
		return 0
	} else {
		pid, err := strconv.Atoi(string(buf[0:n]))
		if err != nil {
			glog.Errorln(err)
			return 0
		} else {
			return pid
		}
	}
}
